<?php
use hyang\App;
// __autoload 自动加载类
spl_autoload_register(function($className){
    $className = str_replace('\\','/',$className);
    if(defined('Dir_Register')){
        foreach(explode(',',Dir_Register) as $v){
            $fname = APP_ROOT.$v.$className.'.php';
            if(is_file($fname)){require_once($fname);return;}
        }        
    }
    $fname = APP_ROOT.$className.'.php';
    if(is_file($fname)){require_once($fname);return;}
    $fname = APP_ROOT.'/'.$className.'.php';
    if(is_file($fname)){require_once($fname);return;}
    if(Pattern != 'PRODUCTION') debug($className."自动加载失败！");
});
//  读取 php 原始数组 配置- 数组对象处理
function config($key=null,$type='objct',$file=null)
{    
    if(is_callable($key)){// 回调函数支持系统调试
        $param = null;
        $option = $key($param);
        if(isset($param['type'])) $type = $param['type'];
        if(isset($param['file'])) $file = $param['file'];
        if(isset($param['key'])) $key = $param['key'];
        elseif(is_string($option)) $key = $option;
    }
    $cfgFile = APP_ROOT.'/App/Common/'.($file? $file:'config').'.php';
    if(!is_file($cfgFile)) $cfgFile = $file;
    if(is_file($cfgFile)){
        require($cfgFile);
        //require_once($file); - 造成config函数不可重复引入文件
        if($type != 'objct'){
            if($key){
                if(array_key_exists($key,$config)) return $config[$key];
                return '';
            }
            return $config;
        }
        if(!empty($config)){
            $obj = (object)$config;
            if($key){
                if(property_exists($obj,$key)) return $obj->$key;
                return '';
            }
            return $obj;
        }
    }
    return null;
}
// 系统调试输出- $feek[if/if+,true/false,type]
function debug($data,$feek=false,$original=false)
{    
    // 支持回调函数- 用于代码测试-面向过程化编程
    if(is_callable($data)){
        $dAdrees = null;
        $callback =  $data($dAdrees);
        if(empty($dAdrees)) goto useReturn;
        else goto useAddrss;
        useAddrss:
            $data = $dAdrees;
            $feek = true;
            if($callback) debug($data,true,true);
            else debug($data,true);
            return;
        useReturn:
            if(empty($callback)) return;
            if(isset($callback['data'])){// 重写参数
                $data = $callback['data'];
                if(isset($callback['feek'])) $feek = $callback['feek']? true:false;
                if(isset($callback['original'])) $original = $callback['original']? true:false;
            }elseif(isset($callback['feek'])){
                unset($callback['feek']);$data = $callback;
            }else $data = $callback;
    }
    // 打印类型
    if(is_string($feek) && 'type' == strtolower($feek)){
        echo'<pre>';
        var_dump($data);
        echo'<pre>';
        return;
    }
    // 如果存在进打印或显示
    if(is_string($feek) && in_array(strtolower($feek),['if','if+'])){
        if(empty($data)) return;
        if('if' == strtolower($feek)) $feek = true;
        else $feek = false;
    }
    $ret = "\r\n快速调试变量(Common/Function)：".date('Y-m-d H:i:s').":::\r\n";
    if(is_object($data) || is_array($data)){
        $data = is_object($data)? (array)$data:$data;
        $data = print_r($data,true);
        $ret = $original? '':$ret;
        $ret .= $feek? '<pre>'.$data.'</pre>':$data;
    }else $ret = ($original? '':$ret).$data;
    if($feek){
        echo $ret;
        return;
    }
    $dir = defined('Debug_Dir')? APP_ROOT.Debug_Dir:__DIR__;
    if(!is_dir($dir)) mkdir($dir);
    $fname = defined('Debug_Suffix')? Debug_Suffix:'.log';
    $fname = $dir.date('Y-m-d').$fname;
    if(is_file($fname)){
        $fh = fopen($fname,'a+');
		fwrite($fh,$ret);//只能写入string
		fclose($fh);
    }else file_put_contents($fname,$ret);
}
// 不定参数- 打印
function println(){
    /*
    $numargs = func_num_args();
    $args = func_get_args();
    if($numargs>0) debug($args,true);
    */
    $numargs = func_num_args();
    $args = func_get_args();
    // 回调函数
    if($numargs>1 && is_callable($args[$numargs-1])){
        $args[$numargs-1](array_pop($args));
    }
    elseif($numargs == 1) debug($args[0],true);
    elseif($numargs>0) debug($args,true);
}
// 调试工具之-脚本输出
function _print($data,$args=null,$br=true)
{
    if(is_callable($data)){
        $str = $data($args);
        $data = $str;
    }
    if(is_null($data)) return;
    if(is_array($data) || is_object($data)){debug($data,true);return;}
    echo $data.($br? '<br>':'');
}
// 数据库绑定-sql 转换
function sql_bind($sql,$bind,$delimiter="'")
{
    // 绑定数据还原原始SQL
    if(is_string($sql) && is_array($bind)){
        foreach($bind as $k=>$v){
            $sql = str_replace(':'.$k,$delimiter.$v.$delimiter,$sql);
        }
        return $sql;
    }
    elseif(is_array($sql) && is_string($sql)){
        foreach($sql as $k=>$v){
            $bind = str_replace($delimiter.$v.$delimiter,':'.$k,$bind);
        }
        return $bind;
    }
    return '';
}
// 打印为json 数据-支持回调函数
function print_json($data,$die=true){
    if(is_callable($data)){
        $newData = null;
        $data($newData);
        if($newData) print_json($newData,true);
    }
    if(is_object($data)) $data = (array)$data;
    if(is_array($data)) $data = json_encode($data);
    header('Content-Type:application/json; charset=utf-8');
    echo $data;
    if($die) die;
}
// 数据文件加载-支持多文件加载
function import($fname,$dir=null,$ext='.php'){
    $array = is_array($fname)? $fname:[$fname];
    foreach($fname as $v){
        $v .= $ext;
        if($dir && is_file($dir.$v)) require_once($dir.$v);
        elseif(is_file($v)) require_once($v);
        elseif(is_file(__DIR__.'/'.$v)) require_once(__DIR__.'/'.$v);
    }
}

// 是否为开发模式
function isDPattern(){
    if(defined('Pattern') && Pattern == 'PRODUCTION') return false;
    return true;
}
// 获取当前的IP地址
function getIp()
{
	if (!empty($_SERVER['HTTP_CLIENT_IP']))	$ip=$_SERVER['HTTP_CLIENT_IP'];
	elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))	$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];//检查IP是从代理传递
	else $ip=$_SERVER['REMOTE_ADDR'];
	return $ip;
}
// 系统时间 $month[int/string]
function sysdate($type=null,$month=null){
	date_default_timezone_set('PRC');
	switch($type){
		case 'date':
			$time = date('Y-m-d');
		case 'time':
			$time = date('H:i:s');
		case 'first':// 当月第一天
			if(empty($month)) $time = date('Y-m-01');
			else{				
				$time = is_numeric($month)? date('Y-').$month.'-01':$month;
				//$time = date_create($time)->format('Y-m-d H:i:s');
				$time = date_format(date_create($time),'Y-m-01');
			}
			break;
		case 'last':// 当月最后一天
			$month = $month? $month:intval(date('n'));
			if($month == 12) $d = (intval(date('Y'))+1).'-01-01';
			elseif(is_numeric($month)) $d = date('Y').'-'.($month+1).'-01';
			else{// 输入日期字符串
				$date = date_create($month);
				$y = date_format($date,'Y');
				$m = date_format($date,'m');
				if($m == 12) $d = (intval($y)+1).'-01-01';
				else $d = $y.'-'.(intval($m)+1).'-01';
			}
			//$time = date_create($d)->add(new DateInterval('P10D'))->format('Y-m-d H:i:s');
			$date = date_create($d);
			date_add($date, date_interval_create_from_date_string('-1 days'));
			$time = date_format($date, 'Y-m-d');
			break;
		default:
			$time = date('Y-m-d H:i:s');
	}
	return $time;
}
// 生成跨端口请求地址
function getPortUrl($url,$port=null){
    return 'http://'.getIp().(is_numeric($port)? ':'.$port:'').$url;
}

/*通过解析获取URL左/右邻值*/
function getUrlBind($name=null,$ogri=false,$position='LEFT'){
    //$url = $_SERVER["REQUEST_URI"];
    $url = $_REQUEST["s"];
    $arr = explode('/',$url);
    if(empty($name)) return $arr;
    $key = array_search($name,$arr);
    if(empty($key)) $key = array_search($name.'.html',$arr);
    if(empty($key)) return '';
    $key = $position == 'LEFT'? $key+1:$key-1;
    if(isset($arr[$key])){
        if($ogri) return $arr[$key];
        $tmpArr = explode('.',$arr[$key]);
        return $tmpArr[0]; 
    }
    return '';
}

/**
    文件压缩	2016/5/23 星期一  
    (PHP 5 >= 5.2.0, PECL zip >= 1.8.0)  开启pecl ;extension=php_zip.dll	;依赖于$this->dirs()方法
    $source		目录资源
    $dest			目标资源[为空则生成到目标资源]
    $fname		zip文件名可选[默认以$source的文件名命名]
**/
function zip($source,$dest=null,$fname=null)
{
    if(!is_dir($source)) return false;
    $dest = !empty($dest) && is_dir($dest)? $dest : $source;
    if(!isset($fname))	$fname = array_pop(explode('/',$source));
    $zipname = $dest.$fname.'.zip';
    $zip = new ZipArchive();
    if($zip->open($zipname,ZipArchive::CREATE) === true){
        $data = dirs($source);
        foreach($data as $v)
        {
            $vdir = $v;
            if(is_file($v))//为文件时
                $vdir = dirname($v).'/';
            $zipArch = str_replace(str_replace($fname.'/','',$source),'',$vdir);//zip内的文件目录
            $zip->addEmptyDir($zipArch);
            if(is_file($v)){
                $zip->addFile($v,$zipArch.basename($v));//第二参数出错时无法加载文件
            }
        }
        $zip->close();
        return '理论上压缩成功';
    }
}

/**
    print_dir 扩展版本~读取目录下所有文件(只列出路径)		测试结果: 2016-05-23.debug
    $dir 示例 ： D:/Joshua/PHP_Web/virtual_root/eiby/epm/Doeeking/  ， 以'/'结果
    $name: 规定前缀
**/
function dirs($dir,$name=null)
{
    $retVal = array();
    if(!is_dir($dir)) return 'Error: 参数dir不是有效目录';
    $data = scandir($dir);
    if(count($data) == 2){// ".",".." 空文件夹
        $fname = $dir;
        if($name)	$name .= array_pop(explode('/',$dir)).'/';
        $retVal[] = $fname;
        return $retVal;
    }
    foreach($data as $v)
    {
        if($v == '.' || $v == '..') continue;
        if(is_dir($dir.$v)){
            $childname = $name? $name.'/'.$v:'';
            $retVal = array_merge($retVal,dirs($dir.$v.'/',$childname));
        }else{
            $retVal[] = ($name? $name.'/' : $dir).$v;
        }
    }
    return $retVal;
}

/*
    yaml 文件解析
    http://pecl.php.net/package/yaml
*/
function yaml($data)
{
    if(@is_file($data)) return yaml_parse_file($data);
    return yaml_parse($data);
}
// 跳转
function go($url){
    header('Location:'.$url);
}
// 解析 csv {$param[file/string],$keyList 键值列默认第一列}
function parse_scv($param,$keyList=1){
    $data = [];
    if(@is_file($param)){
        if(($fh = fopen($param,'r')) !== false){
            $keys = [];
            $i = 0;
            while(($v = fgetcsv($fh)) !== false){
                $i++;
                if($i<$keyList) continue;
                elseif($i == $keyList) $keys = $v;
                elseif(count($keys)>0) $data[] = array_combine($keys,$v);                
            }
        }
    }
    elseif(isset($param['len']) && isset($param['scv'])){
        $len = $param['len'];
        $sorce = array_chunk(@str_getcsv($param['scv']),$len);
        $i = 0;
        $keys = [];
        foreach($sorce as $v){
            $i++;
            if($i<$keyList) continue;
            elseif($i == $keyList) $keys = $v;
            elseif(count($keys)>0 && count($source) == $len) $data[] = array_combine($keys,$v); 
        }
    }
    elseif($param) $data = @str_getcsv($param);
    return $data;
}

// 获取APP类
function _APP($opt=null){
    $option = [
        'version'       => APP::VERSION,
        'controller'    => APP::$Controller,
        'action'        => APP::$Action,
        'source'        => APP::$Source,
        'approot'       => APP::$AppRoot,
        'module'        => APP::$Module,
        'Pattern'       => APP::$Pattern               
    ];
    if($opt){
        if(is_string($opt)) $opt = strtolower($opt);
        if(array_key_exists($opt,$option)) return $option[$opt];
        return '';
    }
    return $option;
    /*
    $app = new APP();debug($app::$Action,true);return;
    return APP::$Action;
    */
}


/*  单字符串提取器=> preg_match
 *  示例： '/Conero/finance/fevent/{:list_no}/other.html' => list_no
 */
 function str_getKey($str,$d1='{:',$d2='}'){
    $start = strpos($str,$d1)+2;
    $len = strpos($str,$d2)-$start;
    $value = substr($str,$start,$len);
    $key = $d1.$value.$d2;
    return [$key=>$value];
 }
 /*  字符串提取器=> preg_match
 *  示例： '/Conero/finance/fevent/{:list_no}/other.html/{:lisa}' => list_no
 */
 function str_engin($str,$pattern=null,$limiter=null){
     $pattern = $pattern? $pattern:'/\{:[a-zA-Z_]*\}/';
     $limiter = $limiter? $limiter:['{:','}'];
     preg_match_all($pattern,$str,$data);
     $data = isset($data[0])? $data[0]:array();
     $retArr = array();
     foreach($data as $v){
         $retArr[$v] = str_replace($limiter[1],'',str_replace($limiter[0],'',$v));
     }
     return $retArr;
 }